const { readFileSync } = require('fs');
import { expect, test as setup } from '@playwright/test';
import { writeFile } from 'fs';
import { isEmpty } from 'lodash';
import { fetchData } from './utils/fetch';

const fileToUnit8Array = (file) => {
  const arrayBuffer = new Uint8Array(file);
  return Array.from(arrayBuffer);
};

const updatePatternsByDesignType = async ({ designType, body }) => {
  return fetchData(`/pattern/${designType}`, 'POST', body);
};
async function handleImportDesign(data) {
  const { uploadType, name, url, file_path, designType, expectations } = data;
  let requestBody = null;

  if (uploadType === 'File Upload') {
    const file = readFileSync(file_path);
    requestBody = JSON.stringify({
      save: true,
      pattern_data: {
        name,
        pattern_file: fileToUnit8Array(file),
      },
    });
  }

  if (uploadType === 'URL') {
    requestBody = JSON.stringify({
      save: true,
      url,
      name,
    });
  }

  const res = (
    await updatePatternsByDesignType({
      designType: designType,
      body: requestBody,
    })
  )?.pop?.();

  const seededDesign = !isEmpty(res) ? { ...res, expectations } : null;
  return seededDesign;
}

const SEED_RESOURCES = {
  designs: [
    {
      uploadType: 'File Upload',
      name: 'Datadog seed content',
      file_path: __dirname + '/' + "../seed-data/Datadog agent on k8's",
      designType: 'Meshery Design',
      expectations: {
        noOfComponents: 2,
        noOfConfigurableComponents: 2,
        noOfAnnotations: 0,
        noOfComponentsWithValidationIssues: 0,
      },
    },
    {
      uploadType: 'File Upload',
      name: 'Design With Validation Errors',
      file_path: __dirname + '/' + '../seed-data/Design With Validation Errors',
      designType: 'Meshery Design',
      expectations: {
        noOfComponents: 8,
        noOfConfigurableComponents: 6,
        noOfAnnotations: 2,
        noOfComponentsWithValidationIssues: 1,
      },
    },
  ],
};

const seedDesigns = async (designs) => {
  return await Promise.allSettled(
    designs.map(async (design) => {
      return await handleImportDesign(design);
    }),
  ).then((res) => res.map((r) => r.value));
};

const dumpDesignsToSampleFile = async (designs) => {
  const designsObj = designs.reduce((acc, design) => {
    acc[design.name] = design;
    return acc;
  }, {});

  const file = __dirname + '/' + '../samples/seededDesigns.js';

  const template = `
    // This file is auto-generated by seedResources.setup.js
    // Do not edit this file manually
    export const Designs = ${JSON.stringify(designsObj, null, 2)};`;

  return writeFile(file, template, (err) => {
    if (err) {
      console.error('Failed to write sample designs file', err);
    }
  });
};

setup('seed-resources', async () => {
  const seededDesigns = (await seedDesigns(SEED_RESOURCES.designs)).filter(Boolean);
  expect(seededDesigns).not.toBeNull();
  expect(seededDesigns).not.toBeUndefined();
  expect(seededDesigns.length).toBeGreaterThan(0);
  await dumpDesignsToSampleFile(seededDesigns);
});
